<script setup lang="ts">
  import { computed, PropType, ref, watch } from 'vue'
  import {
    ElForm,
    ElFormItem,
    ElTable,
    ElTableColumn,
    ElInput,
    FormInstance,
    TableInstance,
  } from 'element-plus'
  import {
    useGetCustomerReceiptAddress,
    useGetLogisticsOptions,
  } from '@/services/pages/return-factory/useReturnFactory'
  import SingleAddress from '@/components/business/address/single-address/SingleAddress.vue'
  import _ from 'lodash'
  import infoTip from '@/config/info-tip'
  import { verifyPhone } from '@/utils/validate'
  import { HMessage, HMessageBox } from '@/components/common/message'
  import { useReturnLogisticsFill } from '@/services/pages/return-factory/useReturnFactory'
  import { useGetGoodList } from '@/services/pages/good/useGood'
  import { useGetCodeList } from '@/services/pages/code/useCodeList'

  const {
    codeList,
    getCodeListLoading,
    getListParam: getSnCodeListParam,
    getList: getSnCodeList,
  } = useGetCodeList()
  const { goodList, getGoodListParam, getGoodListLoading, getGoodList } = useGetGoodList()
  const { receiptAddress, getReceiptAddressLoading, getReceiptAddress } =
    useGetCustomerReceiptAddress()
  const {
    options: logisticsOptions,
    loading: getLogisticsOptionsLoading,
    getOptionsParam,
    getOptions: getLogisticsOptions,
  } = useGetLogisticsOptions()
  const { fillParam, fillLoading, fill } = useReturnLogisticsFill()

  defineOptions({
    name: 'ReturnFactoryReturnLogisticsFillModal',
  })

  interface Good extends ReturnFactoryDetailGood {
    sendBackLogisticsName: string
    sendBackLogisticsNo: string
    goodSelectPopoverVisible: boolean
    snCodeSelectPopoverVisible: boolean
    applyQty: number
  }

  const props = defineProps({
    repairGoodList: {
      type: Array as PropType<Array<ReturnFactoryDetailGood>>,
      required: true,
    },
    returnFactoryId: {
      type: String,
      required: true,
    },
  })

  const emits = defineEmits<{
    (e: 'update'): void
  }>()

  // 表单组件实例
  const formInstance = ref<FormInstance | null>(null)

  // 表格组件实例
  const tableInstance = ref<TableInstance | null>(null)

  // 表单校验规则
  const rules = {
    customerReceiveUsername: [
      { required: true, message: '请输入收货人姓名', trigger: ['change', 'blur'] },
    ],
    customerReceiveProvince: [
      { required: true, message: '请选择收货地址', trigger: ['change', 'blur'] },
      {
        validator: (rule: any, value: any, callback: any) => {
          const { customerReceiveProvince, customerReceiveCity, customerReceiveArea } =
            receiptAddress.value
          if (!customerReceiveProvince || !customerReceiveCity || !customerReceiveArea) {
            callback(new Error('请选择收货地址'))
            return
          }
          callback()
        },
        trigger: ['change', 'blur'],
      },
    ],
    customerReceivePhone: [
      { required: true, message: '请输入收货人手机号', trigger: ['change', 'blur'] },
      {
        validator: (rule: any, value: any, callback: any) => {
          if (!verifyPhone(receiptAddress.value.customerReceivePhone)) {
            callback(new Error('格式不正确'))
            return
          }

          callback()
        },
        trigger: ['change', 'blur'],
      },
    ],
    customerReceiveAddress: [
      { required: true, message: '请输入详细地址', trigger: ['change', 'blur'] },
    ],
  }

  // 用于批量填充物流公司名称
  const allLogisticsEnterprise = ref('')

  // 批量填充物流公司名称弹出框显示状态
  const allLogisticsEnterprisePopoverVisible = ref(false)

  // 用于批量填充物流单号
  const allLogisticsNo = ref('')

  // 批量填充物流单号弹出框显示状态
  const allLogisticsNoPopoverVisible = ref(false)

  // 抽屉显示状态
  const visible = defineModel('visible', { type: Boolean, default: false })

  // 产品列表
  const _goodList = ref<Array<Good>>([])

  // 表格没有填写物流公司或单号的行号
  const errTableRowIndex = ref(-1)

  // 公司收货地址
  const address = computed(() => {
    const {
      customerReceiveProvince,
      customerReceiveCity,
      customerReceiveArea,
      customerReceiveTown,
    } = receiptAddress.value
    return {
      province: customerReceiveProvince,
      city: customerReceiveCity,
      area: customerReceiveArea,
      town: customerReceiveTown,
    }
  })

  /**
   * 隐藏抽屉
   */
  const hideDrawer = () => {
    _goodList.value.length = 0
    receiptAddress.value = {
      customerReceiveProvince: '',
      customerReceiveCity: '',
      customerReceiveArea: '',
      customerReceiveTown: '',
      customerReceiveUsername: '',
      customerReceiveAddress: '',
      customerReceivePhone: '',
      id: '',
    }
    visible.value = false
  }

  /**
   * 获取物流下拉选项
   * @param {String} keyword - 搜索关键字
   */
  const handleGetLogisticsOptions = _.debounce((keyword: string) => {
    if (getOptionsParam.value.name !== keyword) {
      getOptionsParam.value.name = keyword
      getLogisticsOptions()
    }
  }, 600)

  /**
   * 批量填写物流公司名称确定事件
   */
  const onConfirmMultipleFillInLogisticsEnterprise = () => {
    _goodList.value = _goodList.value.map((item) => {
      return {
        ...item,
        sendBackLogisticsName: allLogisticsEnterprise.value,
        sendBackLogisticsNo: item.sendBackLogisticsNo,
      }
    })
    allLogisticsEnterprisePopoverVisible.value = false
    allLogisticsEnterprise.value = ''
  }

  /**
   * 物流公司名称选择事件
   * @param {String} val - 选择的物流公司名称
   * @param {String} index - 表格行索引
   */
  const handleChangeLogisticsEnterprise = (val: string, index: number) => {
    if (val) {
      errTableRowIndex.value = -1
      return
    }
    errTableRowIndex.value = index
  }

  /**
   * 批量填充物流单号输入事件
   * @param {String} val - 输入的单号
   */
  const handleMultipleFillLogisticsNoInput = (val: string) => {
    allLogisticsNo.value = val.replace(/[^\da-zA-Z]/g, '')
  }

  /**
   * 批量填写物流单号确定事件
   */
  const onConfirmMultipleFillInLogisticsNo = () => {
    _goodList.value = _goodList.value.map((item) => {
      return {
        ...item,
        sendBackLogisticsName: item.sendBackLogisticsName,
        sendBackLogisticsNo: allLogisticsNo.value,
      }
    })
    allLogisticsNoPopoverVisible.value = false
    allLogisticsNo.value = ''
  }

  /**
   * 寄回物流单号填充事件
   * @param {Number} index - 表格行索引
   * @param {String} val - 输入的值
   */
  const handleFillLogisticsNoInput = (index: number, val: string) => {
    _goodList.value[index].sendBackLogisticsNo = val.replace(/[^\da-zA-Z]/g, '')
    if (val) {
      errTableRowIndex.value = -1
      return
    }
    errTableRowIndex.value = index
  }

  /**
   * 确定事件
   */
  const onConfirm = async () => {
    if (!formInstance.value) {
      return
    }

    if (!tableInstance.value) {
      return
    }

    try {
      await formInstance.value.validate()
      errTableRowIndex.value = -1
      const noLogisticsInfoIndex = _goodList.value.findIndex(
        (item) => !item.sendBackLogisticsName || !item.sendBackLogisticsNo,
      )
      if (noLogisticsInfoIndex !== -1) {
        tableInstance.value.setScrollTop(noLogisticsInfoIndex * 45)
        errTableRowIndex.value = noLogisticsInfoIndex
        return
      }

      fillParam.value = {
        receiveAddress: receiptAddress.value.customerReceiveAddress,
        receiveArea: receiptAddress.value.customerReceiveArea,
        receiveCity: receiptAddress.value.customerReceiveCity,
        receivePhone: receiptAddress.value.customerReceivePhone,
        receiveProvince: receiptAddress.value.customerReceiveProvince,
        receiveUsername: receiptAddress.value.customerReceiveUsername,
        repairGoodsLogisticsVos: _goodList.value.map((item) => {
          return {
            id: item.id,
            sendBackLogisticsName: item.sendBackLogisticsName,
            sendBackLogisticsNo: item.sendBackLogisticsNo,
            snCode: item.code,
            code: item.goodsCode,
            actualQty: item.applyQty,
          }
        }),
      }
      const res = await fill(props.returnFactoryId)
      if (res.code === 20000) {
        HMessage.success(infoTip.returnFactory.detail.save_logistics_success)
        hideDrawer()
        emits('update')
        return
      }

      HMessageBox.error(res.message)
    } catch (error) {
      // error
    }
  }

  /**
   * 地址选择事件
   * @param {Object} address - 选择的地址
   * @param {String} address.province - 省
   * @param {String} address.city - 市
   * @param {String} address.area - 区
   * @param {String} address.town - 镇
   */
  const handleAddressSelect = (address: {
    province: string
    city: string
    area: string
    town: string
  }) => {
    receiptAddress.value.customerReceiveProvince = address.province
    receiptAddress.value.customerReceiveCity = address.city
    receiptAddress.value.customerReceiveArea = address.area
  }

  const handleGoodCodeInput = (repairGoodIndex: number) => {
    const repairGood = _goodList.value[repairGoodIndex]
    getGoodListParam.value.keyword = repairGood.goodsCode
    _goodList.value[repairGoodIndex].goodSelectPopoverVisible = true
    getGoodList()
  }

  const handleSnCodeInput = (repairGoodIndex: number) => {
    const repairGood = _goodList.value[repairGoodIndex]
    getSnCodeListParam.value.code = repairGood.code
    _goodList.value[repairGoodIndex].snCodeSelectPopoverVisible = true
    getSnCodeList()
  }

  const handleGoodListClick = (index: number, row: GoodItem) => {
    _goodList.value[index].goodsBrand = row.brand
    _goodList.value[index].goodsCode = row.code
    _goodList.value[index].goodsModel = row.model
    _goodList.value[index].goodsName = row.name
    _goodList.value[index].goodsSpec = row.specName
    _goodList.value[index].goodSelectPopoverVisible = false
  }

  const handleSnCodeClick = (index: number, row: SnCode) => {
    _goodList.value[index].goodsBrand = row.brand || ''
    _goodList.value[index].goodsCode = row.goodsCode
    _goodList.value[index].goodsModel = row.goodsModel
    _goodList.value[index].goodsName = row.goodsName
    _goodList.value[index].goodsSpec = row.goodsSpecName
    _goodList.value[index].code = row.securityCode
    _goodList.value[index].snCodeSelectPopoverVisible = false
  }

  watch(
    visible,
    (value) => {
      if (value) {
        getReceiptAddress(props.returnFactoryId)
        _goodList.value = _.cloneDeep(props.repairGoodList).map((item) => {
          return Object.assign(item, {
            sendBackLogisticsName: '',
            sendBackLogisticsNo: '',
            goodSelectPopoverVisible: false,
            snCodeSelectPopoverVisible: false,
            applyQty: 1,
          })
        })
        getLogisticsOptions()
      }
    },
    { immediate: true },
  )
</script>

<template>
  <h-drawer
    v-model="visible"
    title="寄回物流"
    :width="1000"
    unit="px"
    :loading="getReceiptAddressLoading || fillLoading"
  >
    <div class="return-logistics-fill-modal-content">
      <el-form
        ref="formInstance"
        :model="receiptAddress"
        label-position="top"
        inline-message
        :rules="rules"
      >
        <el-form-item label="收货人姓名" prop="customerReceiveUsername">
          <el-input
            v-model.trim="receiptAddress.customerReceiveUsername"
            placeholder="请输入收货人姓名"
          />
        </el-form-item>
        <el-form-item label="收货人手机号" prop="customerReceivePhone">
          <el-input
            v-model.trim="receiptAddress.customerReceivePhone"
            placeholder="请输入收货人手机号"
            maxlength="11"
          />
        </el-form-item>
        <el-form-item label="收货人地址" prop="customerReceiveProvince">
          <single-address
            :address="address"
            placeholder="请选择收货人地址"
            @change="handleAddressSelect"
          />
        </el-form-item>
        <el-form-item label="收货人详细地址" prop="customerReceiveAddress">
          <el-input
            v-model.trim="receiptAddress.customerReceiveAddress"
            placeholder="请输入收货人详细地址"
            maxlength="200"
            resize="both"
            type="textarea"
            show-word-limit
          />
        </el-form-item>
      </el-form>

      <div class="table-wrapper">
        <div class="title">产品列表</div>
        <div class="table">
          <el-table ref="tableInstance" :border="true" stripe height="100%" :data="_goodList">
            <!-- 序号 -->
            <el-table-column width="50" label="序号" fixed="left" :align="'center'" type="index" />

            <!-- 条码 -->
            <el-table-column width="160" label="条码" prop="code">
              <template #default="{ row, $index }">
                <el-popover
                  placement="bottom"
                  :width="600"
                  trigger="click"
                  :visible="row.snCodeSelectPopoverVisible"
                >
                  <template #reference>
                    <el-input
                      v-model="row.code"
                      placeholder="请输入条码"
                      clearable
                      @input="handleSnCodeInput($index)"
                    />
                  </template>
                  <el-table
                    v-loading="getCodeListLoading"
                    :data="codeList"
                    :border="true"
                    stripe
                    :max-height="400"
                    @row-click="(snCode: SnCode) => handleSnCodeClick($index, snCode)"
                  >
                    <el-table-column type="index" width="50" :align="'center'" label="序号" />
                    <el-table-column width="100" prop="securityCode" label="条码" />
                    <el-table-column min-width="100" prop="goodsName" label="商品名称" />
                    <el-table-column width="100" prop="goodsCode" label="商品编号" />
                    <el-table-column width="100" prop="goodsSpecName" label="规格" />
                    <el-table-column width="100" prop="goodsType" label="分类" />
                  </el-table>
                </el-popover>
              </template>
            </el-table-column>

            <!-- 商品编号 -->
            <el-table-column width="140" label="商品编号" prop="goodsCode">
              <template #default="{ row, $index }">
                <el-popover
                  placement="bottom"
                  :width="600"
                  trigger="click"
                  :visible="row.goodSelectPopoverVisible"
                >
                  <template #reference>
                    <el-input
                      v-model.trim="row.goodsCode"
                      placeholder="请输入商品编号"
                      clearable
                      :disabled="Number(row.recommend) !== 4"
                      @input="handleGoodCodeInput($index)"
                    />
                  </template>
                  <el-table
                    v-loading="getGoodListLoading"
                    :data="goodList"
                    :border="true"
                    stripe
                    :max-height="400"
                    @row-click="(good: GoodItem) => handleGoodListClick($index, good)"
                  >
                    <el-table-column type="index" width="50" :align="'center'" label="序号" />
                    <el-table-column
                      min-width="150"
                      show-overflow-tooltip
                      prop="name"
                      label="商品名称"
                    />
                    <el-table-column
                      width="100"
                      show-overflow-tooltip
                      prop="code"
                      label="商品编号"
                    />
                    <el-table-column
                      width="100"
                      show-overflow-tooltip
                      prop="specName"
                      label="规格"
                    />
                    <el-table-column width="100" show-overflow-tooltip prop="unit" label="单位" />
                  </el-table>
                </el-popover>
              </template>
            </el-table-column>

            <!-- 商品名称 -->
            <el-table-column width="160" label="商品名称" prop="goodsName" show-overflow-tooltip />

            <!-- 规格 -->
            <el-table-column width="100" label="规格" prop="goodsSpec" show-overflow-tooltip />

            <!-- 型号 -->
            <el-table-column width="100" label="型号" prop="goodsModel" show-overflow-tooltip />

            <!-- 型号 -->
            <el-table-column width="140" label="申请数量" prop="goodsModel">
              <template #default="{ row }">
                <el-input v-model.trim.number="row.applyQty" placeholder="请输入申请数量" />
              </template>
            </el-table-column>

            <!-- 寄回物流公司名称 -->
            <el-table-column label="寄回物流公司" width="200">
              <template #header>
                <div class="table-cell-header">
                  <span>寄回物流公司</span>
                  <el-popover
                    placement="top"
                    trigger="click"
                    :width="260"
                    :visible="allLogisticsEnterprisePopoverVisible"
                  >
                    <div class="multiple-fill-in-logistics-enterprise">
                      <el-input
                        v-model.trim="allLogisticsEnterprise"
                        placeholder="请输入寄回物流公司"
                      />
                      <h-button type="primary" @click="onConfirmMultipleFillInLogisticsEnterprise">
                        确定
                      </h-button>
                    </div>
                    <template #reference>
                      <h-plain-button
                        :height="16"
                        :padding-lr="4"
                        @click="
                          allLogisticsEnterprisePopoverVisible =
                            !allLogisticsEnterprisePopoverVisible
                        "
                      >
                        批量
                      </h-plain-button>
                    </template>
                  </el-popover>
                </div>
              </template>
              <template #default="{ row, $index }">
                <el-tooltip
                  :visible="$index === errTableRowIndex && !row.sendBackLogisticsName"
                  :content="infoTip.returnFactory.detail.no_fill_logistics_enterprise"
                  placement="top"
                >
                  <el-input
                    v-model.trim="row.sendBackLogisticsName"
                    placeholder="请输入寄回物流公司"
                  />
                </el-tooltip>
              </template>
            </el-table-column>

            <!-- 寄回物流单号 -->
            <el-table-column label="寄回物流单号" width="160">
              <template #header>
                <div class="table-cell-header">
                  <span>寄回物流单号</span>
                  <el-popover
                    v-model:visible="allLogisticsNoPopoverVisible"
                    placement="top"
                    trigger="click"
                    :width="260"
                  >
                    <div class="multiple-fill-in-logistics-enterprise">
                      <el-input
                        v-model.trim="allLogisticsNo"
                        placeholder="请输入寄回物流单号"
                        clearable
                        @input="handleMultipleFillLogisticsNoInput"
                      />
                      <h-button type="primary" @click="onConfirmMultipleFillInLogisticsNo">
                        确定
                      </h-button>
                    </div>
                    <template #reference>
                      <h-plain-button :height="16" :padding-lr="4">批量</h-plain-button>
                    </template>
                  </el-popover>
                </div>
              </template>
              <template #default="{ row, $index }">
                <el-tooltip
                  :visible="$index === errTableRowIndex && !row.sendBackLogisticsNo"
                  :content="infoTip.returnFactory.detail.no_fill_logistics_no"
                  placement="top"
                >
                  <el-input
                    v-model.trim="row.sendBackLogisticsNo"
                    placeholder="请输入寄回物流单号"
                    maxlength="60"
                    clearable
                    @input="(val: string) => handleFillLogisticsNoInput($index, val)"
                  />
                </el-tooltip>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </div>
    <template #footer>
      <h-button is-modal type="primary" @click="onConfirm">确定</h-button>
      <h-button is-modal @click="hideDrawer">取消</h-button>
    </template>
  </h-drawer>
</template>

<style scoped lang="scss">
  .multiple-fill-in-logistics-enterprise {
    display: flex;
    column-gap: 5px;
  }

  .return-logistics-fill-modal-content {
    display: flex;
    flex-direction: column;
    row-gap: 36px;
    height: 100%;

    :deep(.el-form) {
      display: grid !important;
      grid-template-columns: repeat(2, 1fr);
      column-gap: 24px;
      row-gap: 12px;

      .el-form-item {
        .el-form-item__label {
          margin-bottom: 3px;
          height: 16px;
          line-height: 16px;
        }

        .el-form-item__content {
          .el-textarea {
            .el-textarea__inner {
              width: 100% !important;
              height: 28px;
              min-height: 28px !important;
              max-height: 120px !important;
            }
          }

          .el-form-item__error {
            margin: 3px 0 0 0;
            padding: 0;
          }
        }
      }
    }

    .table-wrapper {
      display: flex;
      flex-direction: column;
      row-gap: 6px;
      flex: 1;
      height: 0;

      .title {
        font-size: 12px;
      }

      .table {
        max-height: calc(100% - 22px);
      }

      .table-cell-header {
        display: flex;
        align-items: center;
        column-gap: 5px;
      }
    }
  }
</style>
